/* This DOS utility takes one large binary file and splits it into 16k page *
 * blocks (16384 bytes/4000hex bytes) for use on the ZAX system. Since the  *
 * ZAX does not support binary loads of one large file. The files are given *
 * names denoting which page they should be loaded to, e.g. PAGE00.HEX, and *
 * up to PAGE1F.HEX maximum. Then one simply needs to use a batch file to   *
 * load the pages into the target RAM pages they belong in. I found this of *
 * use when I had a ROM image (binary) and did not have the correct cart or *
 * ROMs to to be able to run it on a stand-alone GameGear.                  *
 *					written by Paul Hutchinson								 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "dos.h"


FILE	*infile, *outfile;  /* input & output files */

int ch,HiNibble,LoNibble,HiHex,LoHex;

void Nibblet(unsigned char byte)
{

		HiNibble=(byte >> 4) & 15;
		if (HiNibble < 10)
			HiHex = HiNibble+48;
		else
			HiHex = HiNibble+55;
		LoNibble=byte & 15;
		if (LoNibble < 10)
			LoHex = LoNibble+48;
		else
			LoHex = LoNibble+55;

}

void BinToHex(void)
{
	unsigned char	done,l,length,checksum,page;
	unsigned char	bytes[33];
	unsigned char	PageFile[11]="PAGE00.HEX";
	unsigned long	pageaddress;
	unsigned long	ByteCount;
	unsigned long	address;

	done=0;
	address=0;
	page=0;
	
	while ((!done) && (page<32))
	{
		Nibblet(page);
		PageFile[4]=HiHex;
		PageFile[5]=LoHex;

		if ((outfile = fopen(PageFile, "w")) == NULL)
		{
			fprintf(stderr, "BIN2PAGE: Unable to create file: %s\n", PageFile);
			return;
		}
		ByteCount=0;
		if (page++<3)
			pageaddress=address;
		else
			pageaddress=32768;
		while ((!done) && (ByteCount < 16384))
		{
			length=0;
			checksum=0;
			while (length < 32)
			{
				if	((ch = getc(infile)) == EOF)
				{
					done = 1;
					break;
				}
				bytes[++length] = ch;
				ByteCount++;
				address++;
			}
	
	
			Nibblet(length);
			fprintf(outfile,":%c%c",HiHex,LoHex);
			checksum = checksum + 16*HiNibble + LoNibble;

			ch = (pageaddress >> 8) & 255;
			Nibblet(ch);
			fprintf(outfile,"%c%c",HiHex,LoHex);
			checksum = checksum + 16*HiNibble + LoNibble;
	
			ch = pageaddress & 255;
			Nibblet(ch);
			fprintf(outfile,"%c%c",HiHex,LoHex);
			checksum = checksum + 16*HiNibble + LoNibble;
	
			Nibblet(0);
			fprintf(outfile,"%c%c",HiHex,LoHex);
			checksum = checksum + 16*HiNibble + LoNibble;
	
			pageaddress += length;
	
			for (l=1; l<length+1; l++)
			{
				Nibblet(bytes[l]);
				fprintf(outfile,"%c%c",HiHex,LoHex);
				checksum = checksum + 16*HiNibble + LoNibble;
	
			}
			ch = 256-checksum;
			Nibblet(ch);
			fprintf(outfile,"%c%c\n",HiHex,LoHex);
	
		}
		fprintf(outfile,":00000001FF\n");
		fclose(outfile);
	}
}


int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		printf("BIN2PAGE: convert file into Intel Hex Pages\n");
		printf("Usage: BIN2PAGE infile\n");
		return EXIT_FAILURE;
	}
	if ((infile = fopen(argv[1], "rb")) == NULL)
	{
		fprintf(stderr, "BIN2PAGE: Unable to open file: %s\n", argv[1]);
		return EXIT_FAILURE;
	}

	BinToHex();

	fclose(infile);
	fclose(outfile);

	return EXIT_SUCCESS;
}




